/* Turska Framework/UI library (Turs2)
 * Copyright 2003-2010 Jetro Lauha
 * All rights reserved.
 * Web: http://iki.fi/jetro/turska/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of EITHER:
 *   (1) The GNU Lesser General Public License as published by the Free
 *       Software Foundation; either version 2.1 of the License, or (at
 *       your option) any later version. The text of the GNU Lesser
 *       General Public License is included with this library in the
 *       file LICENSE-LGPL.txt.
 *   (2) The BSD-style license that is included with this library in
 *       the file LICENSE-BSD.txt.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
 * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details.
 *
 * $Id: T2Font.h 157 2010-01-01 23:31:43Z jlauha $
 * $Revision: 157 $
 */

#ifndef T2FONT_H_INCLUDED
#define T2FONT_H_INCLUDED


namespace turska
{

    //! Interface for font class implementations.
    /*! \note Current API and implementation details are potentially subject to
     *        some changes which may break backwards compatibility:
     * \todo Support for proper font metrics (baseline, ascent, descent, ...).
     */
    class Font
    {
    public:

        class StringRowParser
        {
        public:
            StringRowParser(Font *font, const C8 *string, TREAL scale = 1, TREAL wrapAreaWidth = 0, UI32 substrLength = 0);
            //! Resets row parser. Returns true if successful, or false otherwise.
            bool reset(Font *font, const C8 *string, TREAL scale = 1, TREAL wrapAreaWidth = 0, UI32 substrLength = 0);
            //! Returns true if there was a row to return. Row info is written to arguments.
            bool getNextRow(const C8 *&oRowStart, UI32 &oRowLength, TREAL *oRowWidth);
            //! Returns true if whole string has been parsed, or false otherwise.
            bool finished() const { return mDone; }
            //! Returns amount of rows returned so far.
            I32 getResultRowCount() const { return mResultRowCount; }
        protected:
            Font *mFont;
            const C8 *mString;
            TREAL mScale, mWrapAreaWidth;
            I32 mMaxLength;
            bool mWordWrapping;
            TREAL mSpacing, mSpaceWidth;
            TREAL mResultWidth;
            I32 mResultRowCount;
            I32 mTotalChars;
            const C8 *mCurrentRowStart, *mCurrentWordStart;
            I32 mCurrentRowLength, mCurrentWordLength;
            TREAL mCurrentRowWidth;
            bool mDone;
        };

        enum FONT_FLAG
        {
            FF_HANDLE_BACKSLASH_ESCAPES = 0x00000001,
            FF_DEFAULT_FLAGS = FF_HANDLE_BACKSLASH_ESCAPES
        };

        Font() : mLoaded(false), mDrawMode(IDM_NORMAL), mFlags(FF_DEFAULT_FLAGS) {}
        virtual ~Font() {}

        //! Sets new flags.
        void setFlags(UI32 flags) { mFlags = flags; }

        //! Returns current flags. \sa FONT_FLAG
        UI32 getFlags() const { return mFlags; }

        //! Does any initialization the object needs before it is ready for use.
        /*!
         * \return TRUE if successful or FALSE otherwise.
         */
        virtual bool init() = 0;

        //! Reloads the font.
        /*!
         * Sets the internal loaded state to true if loading was successful
         * and FALSE otherwise.
         * \return true if successful or false otherwise.
         */
        virtual bool reload() = 0;

        //! Returns TRUE if the font is loaded or FALSE otherwise.
        bool isLoaded() const { return mLoaded; }

        //! Sets horizontal character spacing.
        virtual void setCharacterSpacing(I32 spacing) = 0;
        //! Returns horizontal character spacing.
        virtual I32 getCharacterSpacing() = 0;
        //! Returns height of the font.
        virtual I32 getFontHeight() = 0;
        //! Returns height of the font with given scale.
        virtual TREAL getFontHeight(TREAL scale) = 0;
        //! Returns true if font contains the given character.
        virtual bool hasCharacter(UI32 character) = 0;

        //! Returns width of given (sub-)string in given scale.
        virtual TREAL getStringWidth(const C8 *string, TREAL scale, I32 substrLength = -1) = 0;

        //! Finds out metrics of given text (sub-)string in given scale. Returns number of rows in text.
        virtual I32 getStringMetrics(TREAL &oWidth, TREAL &oHeight, const C8 *string,
                                     TREAL scale = 1, TREAL wrapAreaWidth = 0, UI32 substrLength = 0);

        //! Sets draw mode for glyphs. \sa IMAGE_DRAW_MODE
        void setDrawMode(IMAGE_DRAW_MODE drawMode) { mDrawMode = drawMode; }
        //! Returns draw mode.
        IMAGE_DRAW_MODE getDrawMode() const { return mDrawMode; }

        //! Draws a string.
        /*!
         * \param x X-coordinate of the origin for the string.
         * \param y Y-coordinate of the origin for the string.
         * \param string string to draw.
         * \param flags flags to control how the string is positioned and
         *              drawn. \sa IF_ALIGN flags in IMAGE_FLAG.
         * \param scale relative scale to draw with.
         * \param color color and alpha to use.
         * \param substrLength length of substring to draw, or -1 to draw whole string.
         * \return string width.
         */
        virtual TREAL drawString(TREAL x, TREAL y, const C8 *string,
                                UI32 flags = IF_ALIGN_TOP_LEFT, TREAL scale = 1,
                                const Color &color = Color(0xffffffff), I32 substrLength = -1) = 0;

        //! Draws a text block.
        /*! Processes newlines and supports word wrapping to given width.
         * \param x X-coordinate of the origin for the text.
         * \param y Y-coordinate of the origin for the text.
         * \param text text to draw.
         * \param flags flags to control how text is positioned and drawn. Horizontal flags
         *              are handled per row and vertical flags for whole block. \sa IF_ALIGN flags in IMAGE_FLAG.
         * \param scale relative scale to draw with.
         * \param color color and alpha to use.
         * \param substrLength length of substring to draw, or 0 to draw whole text.
         * \return number of rows in drawn text.
         */
        virtual I32 drawText(TREAL x, TREAL y, const C8 *text,
                             UI32 flags = IF_ALIGN_TOP_LEFT, TREAL scale = 1, TREAL wrapAreaWidth = 0,
                             const Color &color = Color(0xffffffff), UI32 substrLength = 0);

    protected:

        bool mLoaded;
        IMAGE_DRAW_MODE mDrawMode;
        UI32 mFlags;

    }; // class Font

} // namespace turska


#endif // !T2FONT_H_INCLUDED
